/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  							 script_creature_action.cpp

	$Header: /heroes4/script_creature_action.cpp $

	$NoKeywords: $

 ************************************************************************/

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "script_creature_action.h"

#include "adventure_frame.h"
#include "basic_dialog.h"
#include "creature.h"
#include "dialog_full_army.h"
#include "player.h"
#include "sized_int_types.h"
#include "streambuf_operators.h"

namespace {
	static int g_number_removed = 0;
	static t_creature_array* g_creature_array = NULL;
};

// --------------------------------------------------------------------------
// t_script_creature_action members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_script_creature_action::read_from_map(
	std::streambuf &	stream,
	int					format_version )
{
	if ( !t_script_army_action::read_from_map( stream, format_version ) )
		return false;

	m_creature_type = t_creature_type( get< t_uint16 >( stream ) );
	if ( m_creature_type < 0 || m_creature_type >= k_creature_type_count )
		return false;

	m_quantity = get< t_uint16 >( stream );

	return true;
}

bool t_script_creature_action::read( std::streambuf& stream, int version )
{
	if ( !t_script_army_action::read( stream, version ) )
		return false;

	m_creature_type = get< t_creature_type >( stream );
	
	if ( m_creature_type < 0 || m_creature_type >= k_creature_type_count )
		return false;

	m_quantity = get< t_uint16 >( stream );

	return true;
}

bool t_script_creature_action::write( std::streambuf& stream ) const
{
	if ( !t_script_army_action::write( stream ) )
		return false;

	put< t_creature_type >( stream, m_creature_type );
	put< t_uint16 >( stream, m_quantity );

	return true;
}

void t_script_give_creatures::do_action(t_creature_array* array) const
{
	if ((g_creature_array = array) == NULL) return;

	bool has_room = false;
	for (int i = 0; i < t_creature_array::k_size; i++) {
		t_creature_stack& stack = (*array)[i];
		t_creature* creature = stack.get_creature();
		if ( stack.can_add( get_creature_type() ) )  
			has_room = true;
	}

	if (has_room)
		g_creature_array->add(get_creature_type(), get_quantity());
	else
	{
		if ((array->get_owner() != NULL) && array->get_owner()->is_computer())
			return;
		
		t_creature_array temp_army;
		temp_army.add(get_creature_type(), get_quantity());

		t_adventure_frame* frame = array->get_adventure_frame();
		if (!frame) 
			return;

		t_counted_ptr<t_dialog_full_army> dialog_ptr;
		dialog_ptr = new t_dialog_full_army( frame );
		dialog_ptr->init_dialog( *array, temp_army );
		dialog_ptr->run_modal();
	}
}

void t_script_take_creatures::do_action(t_creature_array* array) const
{
	if ((g_creature_array = array) == NULL) return;
	int amount_pending = get_quantity();
	for (int i = 0; i < t_creature_array::k_size; i++) {
		t_creature_stack& stack = (*array)[i];
		t_creature* creature = stack.get_creature();
		if ( creature && (creature->can_add(get_creature_type())) ) {
			int stack_size = creature->get_number();
			if (stack_size <= amount_pending) {
				t_creature_stack_ptr creature = new t_creature_stack;
				array->swap(creature, i);
				amount_pending -= stack_size;
			} else {
				creature->remove(amount_pending);
				g_number_removed = get_quantity();
				return;
			}
		}
	}

	if (array->empty() || !array->is_alive())
	{
		array->add(get_creature_type(), 1);
		if (amount_pending != get_quantity())
			amount_pending++;
	}
	g_number_removed = get_quantity() - amount_pending;
}


void t_script_take_creatures::add_icons(t_basic_dialog* dialog) const
{
	if (g_number_removed) 
		dialog->add_creature(get_creature_type(), -g_number_removed, false);
}

void t_script_give_creatures::add_icons(t_basic_dialog* dialog) const
{
	if (g_creature_array)
		dialog->add_creature(get_creature_type(), get_quantity(), false);
}
